home *** CD-ROM | disk | FTP | other *** search
/ GFX Sensations 1 / Graphic Sensations - Volume 1.iso / tools / amiga / 3d_tools / irit40s.lha / Irit / cagd_lib / cbzr_pwr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-30  |  5.1 KB  |  157 lines

  1. /******************************************************************************
  2. * CBzr_Pwr.c - Bezier to pawer basis conversion.                  *
  3. *******************************************************************************
  4. * Written by Gershon Elber, Jun. 90.                          *
  5. ******************************************************************************/
  6.  
  7. #include <ctype.h>
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include "cagd_loc.h"
  11.  
  12. static CagdRType BinomCoef(int n, int i);
  13.  
  14. /******************************************************************************
  15. * Convert the given curve from Bezier basis function to Power basis.          *
  16. * Using:                                      *
  17. *                                          *
  18. *      n                                      *
  19. *      __                                      *
  20. *  n      \    j-i n    j   j                              *
  21. * B (t) = /  (-1)  ( ) ( ) t                              *
  22. *  i      --        j   i                              *
  23. *     j=i                                      *
  24. *                         n-i                  *
  25. * Which can be derived by expanding the (1-t)    term in bezier basis          *
  26. * function definition as:                              *
  27. *                                            *
  28. *        n-i                                    *
  29. *           __                                    *
  30. *      n-i  \  n-i      j                              *
  31. * (1-t)   = / (   ) (-t)    using binomial expansion.              *
  32. *        --  j                                  *
  33. *       j=0                                      *
  34. *                                                                 *
  35. * This routine simply take the weight of each Bezier basis function B(t) and  *
  36. * spread it into the different power basis t^j function scaled by:          *
  37. *                                                                 *
  38. *    j-i n    j                                  *
  39. *   (-1)   ( ) ( )                                                           *
  40. *           j   i                                                   *
  41. ******************************************************************************/
  42. CagdCrvStruct *CnvrtBezier2PowerCrv(CagdCrvStruct *Crv)
  43. {
  44.     CagdBType
  45.     IsNotRational = !CAGD_IS_RATIONAL_CRV(Crv);
  46.     int i, j, l,
  47.     n = Crv -> Length,
  48.     MaxCoord = CAGD_NUM_OF_PT_COORD(Crv -> PType);
  49.     CagdRType *PwrP, *BzrP;
  50.     CagdCrvStruct
  51.     *NewCrv = CagdCrvNew(CAGD_CPOWER_TYPE, Crv -> PType, n);
  52.  
  53.     NewCrv -> Order = n;
  54.  
  55.     for (l = IsNotRational; l <= MaxCoord; l++) {
  56.     PwrP = NewCrv -> Points[l];
  57.     BzrP = Crv -> Points[l];
  58.     ZAP_MEM(PwrP, sizeof(CagdRType) * n);
  59.  
  60.     for (i = 0; i < n; i++) {
  61.         for (j = i; j < n; j++) {
  62.         PwrP[j] += BzrP[i] * BinomCoef(n, j) * BinomCoef(j, i) *
  63.                         (((j - i) & 0x01) ? -1 : 1);
  64.         }
  65.     }
  66.     }
  67.  
  68.     return NewCrv;
  69. }
  70.  
  71. /******************************************************************************
  72. * Convert the given curve from Power basis function to Bezier basis.          *
  73. * Using:                                      *
  74. *                                          *
  75. *      n    j                                      *
  76. *      __  ( )                                      *
  77. *   i  \    i     n                                  *
  78. *  t = /  ----- B (t)                                  *
  79. *      --   n     j                                  *
  80. *      j=i ( )                                      *
  81. *        i                                      *
  82. *                                                                 *
  83. * This routine simply take the weight of each Power basis function t^i and    *
  84. * spread it into the different basis basis function B(t) scaled by:          *
  85. *                                                                 *
  86. *     j   / n                                      *
  87. *    ( ) / ( )                                                           *
  88. *     i /   i                                                       *
  89. ******************************************************************************/
  90. CagdCrvStruct *CnvrtPower2BezierCrv(CagdCrvStruct *Crv)
  91. {
  92.     CagdBType
  93.     IsNotRational = !CAGD_IS_RATIONAL_CRV(Crv);
  94.     int i, j, l,
  95.     n = Crv -> Length,
  96.     MaxCoord = CAGD_NUM_OF_PT_COORD(Crv -> PType);
  97.     CagdRType *PwrP, *BzrP;
  98.     CagdCrvStruct
  99.     *NewCrv = BzrCrvNew(n, Crv -> PType);
  100.  
  101.     for (l = IsNotRational; l <= MaxCoord; l++) {
  102.     PwrP = Crv -> Points[l];
  103.     BzrP = NewCrv -> Points[l];
  104.     ZAP_MEM(BzrP, sizeof(CagdRType) * n);
  105.  
  106.     for (i = 0; i < n; i++) {
  107.         for (j = i; j < n; j++) {
  108.         BzrP[j] += PwrP[i] * BinomCoef(j, i) / BinomCoef(n, i);
  109.         }
  110.     }
  111.     }
  112.  
  113.     return NewCrv;
  114. }
  115.  
  116. /******************************************************************************
  117. * Evaluate the following:                              *
  118. *             n         n!                          *
  119. *            ( ) = -------------                      *
  120. *             i    i! * (n - i)!                      *
  121. ******************************************************************************/
  122. static CagdRType BinomCoef(int n, int i)
  123. {
  124.     int j;
  125.     CagdRType c = 1.0;
  126.  
  127.     if ((n >> 1) > i) {                /* i is less than half of n: */
  128.     for (j = n - i + 1; j <= n; j++) c *= j;
  129.     for (j = 2; j <= i; j++) c /= j;
  130.     }
  131.     else {
  132.     for (j = i + 1; j <= n; j++) c *= j;
  133.     for (j = 2; j <= n - i; j++) c /= j;
  134.     }
  135.  
  136.     return c;
  137. }
  138.  
  139. /******************************************************************************
  140. * Power to Bezier conversion from surfaces.                      *
  141. ******************************************************************************/
  142. CagdSrfStruct *CnvrtPower2BezierSrf(CagdSrfStruct *Srf)
  143. {
  144.     FATAL_ERROR(CAGD_ERR_NOT_IMPLEMENTED);
  145.     return NULL;
  146. }
  147.  
  148. /******************************************************************************
  149. * Bezier to Power conversion from surfaces.                      *
  150. ******************************************************************************/
  151. CagdSrfStruct *CnvrtBezier2PowerSrf(CagdSrfStruct *Srf)
  152. {
  153.     FATAL_ERROR(CAGD_ERR_NOT_IMPLEMENTED);
  154.     return NULL;
  155. }
  156.  
  157.